package com.example.xcService.pojo.channels.impl;

import com.alibaba.fastjson.JSONObject;
import com.example.xcService.pojo.channels.ChannelResult;
import com.example.xcService.pojo.channels.ChannelService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/*
* 掌阅
* */
@Slf4j
public class Plugin_ECARD_P022 implements ChannelService {

    @Override
    public ChannelResult QueryBalance(JSONObject apiConfig) {
        System.out.println("成功调用了QueryBalance");
        return  ChannelResult.success("success");
    }


    @Override
    public ChannelResult Submit(JSONObject apiConfig, Map<String, Object> data) {
        try {
            String AccountVal = String.valueOf(data.get("AccountVal"));
            if (Pattern.matches("^1[3456789]\\d{9}$", AccountVal) != true) {
                return  ChannelResult.error("手机号码异常");
            }

            LinkedHashMap<String, String> params = new LinkedHashMap<>();
            params.put("phone",AccountVal);
            params.put("orderId",String.valueOf(data.get("ChannelOrderCode")));
            params.put("subId",String.valueOf(data.get("SUPProductId")));
            params.put("channelId",apiConfig.getString("channelId"));

            String submitUrl = apiConfig.getString("SubmitUrl");
            String appId = apiConfig.getString("AppId");
            String secretKey = apiConfig.getString("secretKey");
            String time = String.valueOf(System.currentTimeMillis() / 1000L);
            String partUrl = getPartUrl(submitUrl);
            String sign = sign(params, appId, time, secretKey, partUrl);

            String req = HttpPost(time, appId, sign, submitUrl, params);
            JSONObject parseObject = JSONObject.parseObject(req);
            String code = parseObject.getString("code");
            String msg = parseObject.getString("msg");
            String body = parseObject.getString("body");
            JSONObject BODY = JSONObject.parseObject(body);
            if (code.equals("0")) {
                String status = BODY.getString("status");
                if (status.equals("1")) {
                    return ChannelResult.success("充值成功");
                }
            }
            if (code.equals("30001") || code.equals("30004") || code.equals("30006") ) {
                return ChannelResult.error(msg);
            }
            return ChannelResult.FAILED("充值失败##"+msg);

        }catch (Exception e){
            e.printStackTrace();
            log.error("掌阅提交订单接口错误：",e);
            return  ChannelResult.error("掌阅提交订单接口错误");
        }
    }

    @Override
    public ChannelResult Query(JSONObject apiConfig, Map<String, Object> data) {
        System.out.println("成功调用了Query");
        return  ChannelResult.success("success");
    }


    @Override
    public ChannelResult Notify(JSONObject apiConfig, Map<String, Object> data) {
        System.out.println("成功调用了Notify");
        return  ChannelResult.success("success");
    }



    public static String HttpPost(String Timestamp,String AppId,String Sign,String url, Map<String,String> param) {
        String result = "";
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();

        // 创建Post请求
        HttpPost httpPost = new HttpPost(url);

        // 响应模型
        CloseableHttpResponse response = null;
        try {
            // 设置ContentType(注:如果只是传普通参数的话,ContentType不一定非要用application/json)
            httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
            httpPost.setHeader("Timestamp",Timestamp);
            httpPost.setHeader("AppId",AppId);
            httpPost.setHeader("Sign",Sign);
            // 参数设置
            List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
            for (Map.Entry<String, String> entry : param.entrySet()) {
                params.add(new BasicNameValuePair( entry.getKey(),
                        entry.getValue()));
            }
            UrlEncodedFormEntity formEntity=new UrlEncodedFormEntity(params, StandardCharsets.UTF_8);

            httpPost.setEntity(formEntity);

            log.info("httpPost请求："+url+"?"+JSONObject.toJSONString(param));
            // 由客户端执行(发送)Post请求
            response = httpClient.execute(httpPost);
            // 从响应模型中获取响应实体
            HttpEntity responseEntity = response.getEntity();

            System.out.println("响应状态为:" + response.getStatusLine());
            if (responseEntity != null) {
                result=EntityUtils.toString(responseEntity);
                log.info("httpPost请求返回："+JSONObject.toJSONString(result));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                // 释放资源
                if (httpClient != null) {
                    httpClient.close();
                }
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return  result;
    }


    public String sign(Map<String, String> params, String appId, String ts,
                       String secretKey, String urlPath) {
        params.put("Timestamp", ts);
        params.put("AppId", appId);
        params.put("Secret", secretKey);
        params.put("UrlPath", urlPath);
        List<String> keyList = new ArrayList<>();
        params.entrySet().stream().sorted(Map.Entry.<String,
                String>comparingByKey())
                .forEachOrdered(x-> keyList.add(x.getKey()+ "=" + x.getValue()));
        byte[] data = String.join("&", keyList).getBytes();
        //sha256签名
        return DigestUtils.sha256Hex(data);
    }

    public static String getPartUrl(String url) {
        String partUrl = "";
        if (url != null && url.contains("://")) {
            // 使用正则表达式获取"://"之后的部分
            partUrl = url.replaceAll("(?i)(https?://[^/?]+)", "");
        }
        return partUrl;
    }


}
